<--- %%NOBANNER%% --> trend.sas
 BackForward

/*------------------<--  Start of Description -->--------------------\
|   THIS MACRO PERFORMS THE ARMITAGE TREND TEST FOR PROPORTIONS.     |
|   WE ASSUME WE HAVE K PROPORTIONS P(I), I=1,2,..,K, OCCURRING IN   |
|   K GROUPS WHICH ARE NATURALLY ORDERED(MILD, MODERATE, SEVERE SAY) |
|   EACH P(I)=n/N, WHERE n=NUMBER OF CASES OR EVENTS AND N=POPULA-   |
|   TION SIZE IN GROUP I.  ONE THEN ASSIGNS A NUMERIC SCORE, X(I),   |
|   TO EACH OF THE K GROUPS, E.G. -1=MILD, 0=MODERATE, 1=SEVERE.     |
|   THE TREND TEST IS A TEST OF THE SIGNIFICANCE OF THE REGRESSION   |
|   OF P(I) ON X(I).                                                 |
|                                                                    |
|   THE INPUT DATASET MUST HAVE ONE ROW FOR EACH P(I). THE DATASET   |
|   MUST CONTAIN VARIABLES FOR GROUP, X, n AND N.                    |
|--------------------<--  End of Description -->---------------------|
|--------------------------------------------------------------------|
|--------------<--  Start of Files or Arguments Needed -->-----------|
| Arguments:                                                         |
|     INDATA=INPUT DATASET NAME, ONE ROW PER GROUP.                  |
|     GROUP=THE GROUP VARIABLE(NUMERIC OR CHARACTER).                |
|           THIS IS USED ONLY AS A LABEL OR IDENTIFIER.              |
|     X=THE X VARIABLE FOR THE REGRESSION.                           |
|     CASE_N=THE VARIABLE CONTAINING THE NUMBER OF CASES             |
|            (n) PER GROUP.                                          |
|     N=THE POPULATION SIZE FOR THE GROUP.                           |
| THE MACRO CREATES A NEW DATASET CALLED OUTDATA WHICH CONTAINS      |
|   THE ORIGINAL DATASET PLUS TWO NEW VARIABLES, P(=n/N), AND        |
|   PHAT, THE PREDICTED VALUE OF P FROM THE REGRESSION.  A PLOT      |
|   OF P VS PHAT MAY BE OF INTEREST.                                 |
|                                                                    |
| THE OUTPUT CONTAINS THREE SECTIONS.  THE FIRST SECTION LABELED     |
|   'INPUT DATASET' LISTS THE INPUT DATA PLUS P AND PHAT.  THE       |
|   SECTION LABELED 'TEST STATISTICS' CONTAINS THE CHI-SQUARE,       |
|   DF, AND P VALUES OF THE THREE TESTS.  EQUATION 4 IS THE USUAL    |
|   CHI-SQUARE TEST FOR A LINEAR TREND.  THE SECTION  LABELED        |
|   'REGRESSION STATISTICS' CONTAINS THE SLOPE ESTIMATE(B) AND ITS   |
|   STANDARD ERROR AND ALSO THE INTERCEPT(A).  EQUATION NUMBERS      |
|   FROM THE ARMITAGE PAPER ARE INDICATED ON THE OUTPUT.             |
|---------------<--  End of Files or Arguments Needed -->------------|
|--------------------------------------------------------------------|
|----------------<--  Start of Example and Usage -->-----------------|
| Usage: %TREND (INDATA, GROUP, X, CASE_N, N);                       |
| REFERENCE: TESTS FOR LINEAR TRENDS IN PROPORTIONS & FREQUENCIES    |
|               P. ARMITAGE, BIOMETRICS 1955,VOL(11),#3,375-385.     |
\-------------------<--  End of Example and Usage -->---------------*/
%MACRO TREND (INDATA, GROUP, X, CASE_N, N);
/*--------------------------------------------\
| Author:  JAMES KUIPER and BERGSTRALH;       |
| Date:    01/14/91;                          |
| Purpose: ARMITAGE TREND TEST FOR PROPORTIONS|
\--------------------------------------------*/
OPTIONS NOCENTER ERRORABEND;

      DATA _TREND1;
         LENGTH  __GRP $ 8;
         SET &INDATA;
         KEEP DUM __GRP &X &CASE_N &N;
         DUM=1;
         __GRP=&GROUP;
         RENAME &X=__X
                &CASE_N=_CASE_N_
                &N=_POP_N_;

      PROC SORT DATA=_TREND1; BY __X;


      DATA _TREND2; SET _TREND1; BY DUM;
         KEEP CASE_T POP_T P K DUM XBAR;
         RETAIN CASE_T 0   POP_T 0   P 0   NX 0;
         CASE_T = CASE_T + _CASE_N_;
         POP_T = POP_T + _POP_N_;
         NX = NX + (_POP_N_ * __X);
         IF LAST.DUM THEN DO;
            P = CASE_T / POP_T;
            K=_N_;
            XBAR = NX / POP_T;
            OUTPUT;
         END;


      DATA _TREND3;
         MERGE _TREND1 _TREND2; BY DUM;
         DROP __GRP _CASE_N_ _POP_N_ S_ SSX P_I __X;
         RETAIN S_ 0  SSX 0  S1_S2 0  S3 0;
         FORMAT P 10.8  B SE_B SE_B_ALT A BEST10.;
         P_I = _CASE_N_ / _POP_N_;
         S_ = S_ + _POP_N_*P_I*(__X-XBAR);
         SSX = SSX + _POP_N_*((__X-XBAR)**2);
         S1_S2 = S1_S2 + _POP_N_*((P_I-P)**2);
         S3 = S3 + _POP_N_*P_I*(1-P_I);
         S1_S2_S3 = POP_T*P*(1-P);

         IF LAST.DUM THEN DO;
           S1 = S_**2 / SSX;

           EQN3 = (S1_S2*POP_T) / S1_S2_S3;
           EQN3_DF = K-1;
           EQN3_P = 1-PROBCHI(EQN3,EQN3_DF);
           EQN3_P = ROUND(EQN3_P,.0001);

           EQN4 = (S1*POP_T) / S1_S2_S3;
           EQN4_DF = 1;
           EQN4_P = 1-PROBCHI(EQN4,1);
           EQN4_P = ROUND(EQN4_P,.0001);

           EQN3_4 = EQN3 - EQN4;
           EQN34_DF = K-2;
           EQN34_P = 1-PROBCHI(EQN3_4,EQN34_DF);
           EQN34_P = ROUND(EQN34_P,.0001);

           B = S_ / SSX;
           VAR_B = (P*(1-P)) / SSX;
           SE_B = SQRT(VAR_B);
           SE_B_ALT = SQRT(S3/((POP_T-K)*SSX));
           CHISQ = B**2 / VAR_B;
           P_VALUE = 1-PROBCHI(CHISQ,1);
           P_VALUE = ROUND(P_VALUE,.0001);

           A =  P - B*XBAR;
           OUTPUT;
         END;


      DATA NEXT; MERGE _TREND1 _TREND3;
         BY DUM;
         KEEP PHAT_I P_I __GRP __X _CASE_N_ _POP_N_ DUM;
         P_I = _CASE_N_ / _POP_N_;
         YHAT = A + B*__X;
         PHAT_I = YHAT;
         FORMAT P_I PHAT_I 10.8;


   DATA _NULL_; SET NEXT(IN=INA) _TREND3;
      BY DUM;
      FILE PRINT N=PS HEADER=H LINESLEFT=L;

      *** A ***;
      IF INA THEN DO;
         PUT @7 __GRP  @18 __X  @27 _CASE_N_  @37 _POP_N_  @47 P_I
             @63 PHAT_I;
      END;

      ELSE DO;
         PUT @5 '_____________________________________________'
             @50 '________________________' / ;
         PUT @25 't=' CASE_T  @35 'T=' POP_T /
             @29 'OVERALL P(= t/T)= ' P;
         IF L LT 24 THEN PUT _PAGE_;
      *********;

         *** B ***;
         PUT  ////   @70 'ARMITAGE';
         PUT  @5 'TEST STATISTICS:'  @39 'CHI SQUARE'  @53 'DF'
              @59 'P VALUE'  @70 'EQUATION' / ;
         PUT  @10 'ALL GROUPS EQUAL'  @41 EQN3  @53 EQN3_DF  @59 EQN3_P
              @72 '(3)';
         PUT @10 'LINEAR TREND'  @41 EQN4  @53 EQN4_DF  @59 EQN4_P
             @72 '(4)';
         PUT @10 'DEPARTURES FROM LINEARITY'  @41 EQN3_4  @53 EQN34_DF
             @59 EQN34_P @70 '(3)-(4)';
         FORMAT EQN3 EQN4 EQN3_4 6.3;
         *********;

         *** C ***;
         PUT ////  @5 'REGRESSION STATISTICS:' / ;
         PUT @10 'COEFFICIENT(B)'  @37 '= ' B  @72 '(5)';
         PUT @10 'SE(B) UNDER NULL'  @37 '= ' SE_B  @70 'SQRT(6)';
         PUT @10 'SE(B) UNDER ALTERNATIVES'  @37 '= ' SE_B_ALT
             @70 'PG. 377';
         PUT @10 'INTERCEPT(A)'  @37 '= ' A    /////;
         *********;

      END;
      RETURN;

      OPTIONS DQUOTE;
      H: IF INA THEN DO;
            PUT //// @5 "ARMITAGE TREND TEST FOR PROPORTIONS(BIOMETRICS"
                @52 "1955,VOL (II),#3,375-385)" //
                @5 "INPUT DATASET:" //  @7 "&GROUP"  @17 "&X"
                @27 "&CASE_N"  @37 "&N"  @51 "P"  @66 "PHAT" /
                @17 "(X)"  @27 "(n)" @37 "(N)"
                @49 "(n/N)" @62 "(PREDICTED P)" / ;
         END;
      OPTIONS NODQUOTE;


      PROC SORT DATA=&INDATA; BY &X;
      PROC SORT DATA=NEXT; BY __X;
      DATA OUTDATA;
         MERGE &INDATA NEXT(KEEP=P_I PHAT_I);
         RENAME P_I=P
                PHAT_I=PHAT;


      PROC DELETE DATA=_TREND1 _TREND2 _TREND3;

   RUN;

%MEND TREND;